﻿#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;

//struct Point
//{
//	int _x;
//	int _y;
//};
//
//int main()
//{
//	int a(4);
//
//	int b = { 2 };
//	int c{ 3 };
//
//	int arr[]{ 1,2,3,4,5 };
//
//	Point p{ 1,2 };
//
//	// C++11中列表初始化也可以适用于new表达式中
//	int* pa = new int{ 5 };
//	cout << *pa << endl;
//	return 0;
//}

//class Date
//{
//public:
//	Date(int year, int month, int day)
//		:_year(year)
//		, _month(month)
//		, _day(day)
//	{
//		cout << "Date(int year, int month, int day)" << endl;
//	}
//private:
//	int _year;
//	int _month;
//	int _day;
//};
//int main()
//{
//	Date d1(2022, 1, 1); // old style
//
//	// C++11支持的列表初始化，这里会调用构造函数初始化
//	Date d2 = { 2022, 1, 2 };
//	Date d3{ 2022, 1, 3 };
//	return 0;
//}

//#include <vector>
//#include <list>
//int main()
//{
//	vector<int> v = { 1,2,3,4 };
//
//	vector<int> v2({ 1,2,3,4 });
//
//	list<int> lt = { 2,4,6,8,9 };
//
//	initializer_list<int> il = { 1,2,3,4,5,6,7,8 };
//
//	vector<int> v3 = il;
//
//	return 0;
//}

//int main()
//{
//	const int x = 1;
//	double y = 2.2;
//	//decltype(x * y) ret; // ret的类型是double
//	//decltype(&x) p;		// p的类型是const int*
//
//	auto ret = x * y;
//	auto p = &x;
//
//	vector<decltype(x* y)> v;
//
//	cout << typeid(ret).name() << endl;
//	cout << typeid(p).name() << endl;
//
//	return 0;
//}

//int main()
//{
//	// 以下的p、b、c、*p都是左值
//	int* p = new int(0);
//	int b = 1;
//	const int c = 2;
//
//	// 以下几个是对上面左值的左值引用
//	int*& rp = p;
//	int& rb = b;
//	const int& rc = c;
//	int& pvalue = *p;
//	return 0;
//}

//int main()
//{
//	double x = 1.1, y = 2.2;
//	// 以下几个都是常见的右值
//	10;
//	x + y;
//	fmin(x, y);
//
//	// 以下几个都是对右值的右值引用
//	int&& rr1 = 10;
//	rr1 = 20;
//	double&& rr2 = x + y;
//	double&& rr3 = fmin(x, y);
//
//	// 这里编译会报错：error C2106: “=”: 左操作数必须为左值
//	/*10 = 1;
//	x + y = 1;
//	fmin(x, y) = 1;*/
//	return 0;
//}


//int main()
//{
//	int a = 10;
//	int b = 3;
//
//	const int& ret = a + b;
//
//	int&& c = move(a);
//	return 0;
//}

//int main()
//{
//	// 左值引用只能引用左值，不能引用右值。
//	int a = 10;
//	int& ra1 = a; // ra为a的别名
//	//int& ra2 = 10;   // 编译失败，因为10是右值
//	
//	// const左值引用既可引用左值，也可引用右值。
//	const int& ra3 = 10;
//	const int& ra4 = a;
//	return 0;
//}

//int main()
//{
//	// 右值引用只能右值，不能引用左值。
//	int&& r1 = 10;
//
//	// message : 无法将左值绑定到右值引用
//	int a = 10;
//	int&& r2 = a;
//	// error C2440: “初始化”: 无法从“int”转换为“int &&”
//
//	// 右值引用可以引用move以后的左值
//	int&& r3 = move(a);
//	return 0;
//}

//#include <string>
//void func1(string s)
//{}
//void func2(const string& s)
//{}
//int main()
//{
//	string s1("hello world");
//	// func1是传值调用要进行拷贝，
//	//func2左值引用做参数减少了拷贝，提高效率
//	func1(s1);
//	func2(s1);
//
//	// string operator+=(char ch) 传值返回存在深拷贝
//	// string& operator+=(char ch) 传左值引用没有拷贝提高了效率
//	s1 += '!';
//	return 0;
//}

#include <assert.h>
#include "string.h"
//int main()
//{
//	bit::string s("hello world");
//	bit::string ret1 = move(s);
//
//	//cout << "-----------------" << endl;
//	//bit::string ret2 = s + '!';
//	return 0;
//}

//int main()
//{
//	bit::string s1;
//	s1 = bit::to_string(1234);
//
//	return 0;
//}


//int main()
//{
//	string s("hello world");
//	string ret1 = move(s);
//	cout << ret1 << endl;
//	return 0;
//}

//#include <list>
//#include <string>
//int main()
//{
//	list<bit::string> l;
//
//	l.push_back(bit::string("2222222"));
//	l.push_back("3333333");
//
//	//bit::string s1("1111");
//	//
//	//lt.push_back(s1);
//	//cout << "-----------" << endl;
//	//lt.push_back(move(s1));
//	return 0;
//}

void Fun(int& x) { cout << "左值引用" << endl; }
void Fun(const int& x) { cout << "const 左值引用" << endl; }
void Fun(int&& x) { cout << "右值引用" << endl; }
void Fun(const int&& x) { cout << "const 右值引用" << endl; }

template<typename T>
void PerfectForward(T&& t)
{
	Fun(forward<T>(t));
}

int main()
{
	PerfectForward(10); // 右值
	int a;
	PerfectForward(a); // 左值
	PerfectForward(move(a));// 右值

	const int b = 8;
	PerfectForward(b);// const 左值
	PerfectForward(move(b)); // const 右值

	return 0;
}

//#include "list.h"
//
//int main()
//{
//	yin::list<bit::string> lt;
//
//	bit::string s1("hello world");
//	lt.push_back(s1);
//
//	lt.push_back(bit::string("hello world"));
//	lt.push_back("hello world");
//
//	return 0;
//}